package com.example.springboot_template.aspect;

import cn.hutool.core.util.StrUtil;
import com.example.springboot_template.common.ErrorCode;
import com.example.springboot_template.common.ResultUtils;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.lang.reflect.Field;

@Component
@Aspect
@Slf4j
public class NotNullAspect {

    //自定义切点
    @Pointcut("@annotation(com.example.springboot_template.annotation.ParamCheckNUll)")
    public void annotationPointcut() {}


    @Around("annotationPointcut()")
    public Object round(ProceedingJoinPoint joinPoint) throws Throwable {
        //log.info("方法执行中");
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();

        String[] params = signature.getParameterNames();//获取所有的参数名称
        Object[] args = joinPoint.getArgs();//获取所有的参数值



        int length = args.length;

        for (int i = 0; i <length ; i++) {
            if (isObjectEmpty(args[i])) {
                String msg = "参数 " + params[i] + " 不能为空";
                log.info(msg);
                return ResultUtils.error(ErrorCode.NULL_ERROR, msg);
            }
        }
        return joinPoint.proceed();

    }
    //使用反射对对象中的属性判空
    private boolean isObjectEmpty(Object obj) throws IllegalAccessException {
        if (obj == null) {
            return true;
        }
        if (obj instanceof String) {
            return !StringUtils.hasText((String) obj);
        }
        for (Field field : obj.getClass().getDeclaredFields()) {
            field.setAccessible(true);
            Object value = field.get(obj);
            if (value == null || (value instanceof String && !StringUtils.hasText((String) value))) {
                return true;
            }
        }
        return false;
    }

}
